import Canvas2Image from './canvas2image.js';
import html2canvas from 'html2canvas';
class Thematic {
    constructor({
        borderDis = Number(($('#themetic-canvas').offsetWidth - $('.img_box').offsetWidth) / 2),
        Canvas = document.getElementById('themetic-canvas'),
        fontSize = 16,
        pointLine = [3, 1],
        lineIsExist = false,
    }) {
        // 图片和canvas间距
        this.borderDis = borderDis;
        // Canvas对象
        this.Canvas = Canvas;
        this.range = 3; // 当经纬度差值小于3度时，将经纬度分成固定份数
        this.fontSize = fontSize;
        this.pointLine = pointLine;
        this.lineIsExist = lineIsExist;
        this.canvasInit();
    }
    testNl() {
        this.testCode = true;
    }
    // 添加或者清除辅助线
    addOrClear(code) {
        this.lineIsExist = code;
        this.judgeAddOrClear();
    }
    // 经纬度框发生变化
    latlngBoxChange(latlngBox) {
        this.delLine();
        this.latlngBox = latlngBox;
        this.judgeAddOrClear();
    }

    canvasInit() {
        this.cxt = this.Canvas.getContext('2d');
        this.cxt.strokeStyle = '#000';
        this.cxt.lineWidth = 1;
        // 绘制一个边框
        this.cxt.strokeRect(0, 0, this.Canvas.offsetWidth - 2, this.Canvas.offsetHeight);
    }
    // 添加或者清除经纬度辅助线
    judgeAddOrClear() {
        this.lineIsExist === true ? this.delLine() : this.addCanvas();
    }
    // 绘制经纬度的canvas
    addCanvas() {
        this.lineIsExist = true;
        // 字体大小
        this.cxt.font = `${this.fontSize}px Arial`;
        this.cxt.strokeStyle = '#000';
        this.cxt.lineWidth = this.pointLine[1];
        this.cxt.beginPath();
        this.cxt.setLineDash([10, 5]);
        this.calculateLoc();
    }
    // 清除绘制的经纬度网
    delLine() {
        this.lineIsExist = false;
        this.cxt.clearRect(1, 1, this.Canvas.offsetWidth - 4, this.Canvas.offsetHeight - 2);
    }

    // 计算经纬点及对应位置
    calculateLoc() {
        let minLat = this.latlngBox[2];
        let maxLat = this.latlngBox[0];
        let minLng = this.latlngBox[3];
        let maxLng = this.latlngBox[1];
        let totleWidth = this.Canvas.offsetWidth - 2 * this.borderDis;
        let totleHeight = this.Canvas.offsetHeight - 2 * this.borderDis;
        let latRate = (maxLat - minLat) / totleHeight;
        let lngRate = (maxLng - minLng) / totleWidth;
        let allLatSignArr = [];
        let allLngSignArr = [];
        if (maxLat - minLat < 3 || maxLng - minLng < 3) {
            allLatSignArr = this.splitRange(maxLat, minLat);
            allLngSignArr = this.splitRange(maxLng, minLng);
        } else {
            // 整数的最小纬度
            let holeMinLat = Math.ceil(minLat);
            // 整数的最大纬度
            let holeMaxLat = Math.floor(maxLat);
            // 整数的最小经度
            let holeMinLng = Math.ceil(minLng);
            // 整数的最小经度
            let holeMaxLng = Math.floor(maxLng);
            allLatSignArr = this.getAllInteger(holeMinLat, holeMaxLat);
            allLngSignArr = this.getAllInteger(holeMinLng, holeMaxLng);
        }
        let latParam = {
            minV: minLat,
            maxV: maxLat,
            rate: latRate,
            distance: totleWidth,
            dataArr: allLatSignArr,
            iStransverse: true,
        };
        this.drawLine(latParam);
        let lngParam = {
            minV: minLng,
            maxV: maxLng,
            rate: lngRate,
            distance: totleHeight,
            dataArr: allLngSignArr,
            iStransverse: false,
        };
        this.drawLine(lngParam);
        this.cxt.stroke();
        this.cxt.closePath();
    }
    // 将两个数分割成固定份数
    splitRange(max, min) {
        let difference = max - min;
        let valueAdded = difference / this.range;
        let arr = [];
        for (let i = 0; i < this.range + 1; i++) {
            arr.push((min + i * valueAdded).toFixed(6));
        }
        return arr;
    }
    // 求出两整数之间的所有整数（包含两整数）
    getAllInteger(min, max) {
        let resData = [];
        let i = min;
        let interval = this.getIntervalNum(max, min);
        for (i; i <= max; i = i + interval) {
            resData.push(i);
        }
        return resData;
    }
    // 计算两个数差值中间的间隔x，使差值之间的数保持在10以内
    getIntervalNum(max, min) {
        let num = max - min;
        let interval = 1;
        while (num > 10) {
            interval++;
            num = (max - min) / interval;
        }
        return interval;
    }
    // 计算并绘制每一条经纬度线
    drawLine(obg) {
        obg.dataArr.forEach((item, index) => {
            let dis = this.decimalAri(item, obg.minV, 'reduction') / obg.rate + this.borderDis;
            if (obg.iStransverse) {
                let allHeight = this.Canvas.height;
                dis = allHeight - dis;
                this.cxt.moveTo(this.borderDis, dis);
                this.cxt.lineTo(this.borderDis - this.pointLine[0], dis);
                this.cxt.moveTo(obg.distance + this.borderDis, dis);
                this.cxt.lineTo(obg.distance + this.borderDis + this.pointLine[0], dis);

                // this.cxt.moveTo(this.borderDis - this.pointLine[0], dis);
                // this.cxt.lineTo(obg.distance + this.borderDis + this.pointLine[0], dis);
                // 绘制数字
                this.cxt.save();
                // if (index === 0 || index === obg.dataArr.length - 1) {
                item = item === 0 ? item + '°' : item > 0 ? item + '°N' : item + '°S';
                // }
                let { width: wText, hText = this.fontSize } = this.cxt.measureText(item);
                // 平移一次画布
                this.cxt.translate(this.borderDis / 2, dis);
                // 旋转画布
                this.cxt.rotate((270 * Math.PI) / 180);
                if (index === 0) {
                    this.cxt.fillText(item, 0, hText / 2);
                } else if (index === obg.dataArr.length - 1) {
                    this.cxt.fillText(item, -wText, hText / 2);
                } else {
                    this.cxt.fillText(item, -wText / 2, hText / 2);
                }
                this.cxt.restore();
                this.cxt.save();
                this.cxt.translate(obg.distance + (this.borderDis * 3) / 2, dis);
                this.cxt.rotate((90 * Math.PI) / 180);
                if (index === 0) {
                    this.cxt.fillText(item, -wText, hText / 2);
                } else if (index === obg.dataArr.length - 1) {
                    this.cxt.fillText(item, 0, hText / 2);
                } else {
                    this.cxt.fillText(item, -wText / 2, hText / 2);
                }
                this.cxt.restore();
            } else {
                this.cxt.moveTo(dis, this.borderDis);
                this.cxt.lineTo(dis, this.borderDis - this.pointLine[0]);

                this.cxt.moveTo(dis, obg.distance + this.borderDis);
                this.cxt.lineTo(dis, obg.distance + this.borderDis + this.pointLine[0]);

                // this.cxt.moveTo(dis, this.borderDis - this.pointLine[0]);
                // this.cxt.lineTo(dis, obg.distance + this.borderDis + this.pointLine[0]);

                // 绘制数字
                // if (index === 0 || index === obg.dataArr.length - 1) {
                item = item === 0 ? item + '°' : item > 0 ? item + '°E' : item + '°W';
                // }
                let { width: wText } = this.cxt.measureText(item);
                if (index === 0) {
                    this.cxt.fillText(item, dis, this.borderDis - 6);
                    this.cxt.fillText(item, dis, obg.distance + 2 * this.borderDis - 6);
                } else if (index === obg.dataArr.length - 1) {
                    this.cxt.fillText(item, dis - wText, this.borderDis - 6);
                    this.cxt.fillText(item, dis - wText, obg.distance + 2 * this.borderDis - 6);
                } else {
                    this.cxt.fillText(item, dis - wText / 2, this.borderDis - 6);
                    this.cxt.fillText(item, dis - wText / 2, obg.distance + 2 * this.borderDis - 6);
                }
            }
        });
    }
    // 处理小数之间运算
    decimalAri(data1, data2, way) {
        data1 = String(data1);
        data2 = String(data2);
        let powNum1 = data1.split('.')[1] ? data1.split('.')[1].length : 0;
        let powNum2 = data2.split('.')[1] ? data2.split('.')[1].length : 0;
        let powNum = powNum1 > powNum2 ? powNum1 : powNum2;
        let zjMax = data1 * Math.pow(10, powNum);
        let zjMin = data2 * Math.pow(10, powNum);
        let res = null;
        if (way === 'add') {
            res = zjMax + zjMin;
        } else if (way === 'reduction') {
            res = zjMax - zjMin;
        } else if (way === 'take') {
            res = zjMax * zjMin;
        } else if (way === 'addition') {
            res = zjMax / zjMin;
        } else {
            res = Math[way](zjMax, zjMin);
        }
        return res / Math.pow(10, powNum);
    }
    // 裁剪地图形成图片
    tailoringMap(exportClass) {
        let x = $('.img_latLng_inf')?.offset().left + this.borderDis;
        let y = $('.img_latLng_inf')?.offset().top + this.borderDis;

        let width = $('.img_latLng_inf').width() - 2 * this.borderDis;
        let height = $('.img_latLng_inf').height() - 2 * this.borderDis;
        return this.makeThematic(exportClass, x, y, width, height);
    }
    // 下载图片
    exportScreenshot(exportClass, thematicName, callBackFun) {
        this.makeThematic(exportClass).then(canvas => {
            let width = canvas.width;
            let height = canvas.height;
            canvas.id = 'self_canvas';
            let img = Canvas2Image.convertToImage(canvas, width, height);
            let dataBlob = this.convertBase64UrlToBlob(img.src);
            let aLink = document.createElement('a');
            aLink.href = URL.createObjectURL(dataBlob);
            aLink.download = thematicName + '.png';
            aLink.click();
            callBackFun();
        });
    }
    // 生成canvas
    makeThematic(exportClass, x, y, width, height) {
        let dom = document.querySelector(exportClass);
        let option = { letterRendering: true }; // 保留字间距
        this.addEle(option, 'x', x);
        this.addEle(option, 'y', y);
        this.addEle(option, 'width', width);
        this.addEle(option, 'height', height);
        return html2canvas(dom, option);
    }
    addEle(obg, key, val) {
        if (val) obg[key] = val;
    }
    // 将base64图片转为blob格式
    convertBase64UrlToBlob(dataurl) {
        try {
            let arr = dataurl.split(',');
            let bstr = atob(arr[1]);
            let n = bstr.length;
            let u8arr = new Uint8Array(n);
            while (n--) {
                u8arr[n] = bstr.charCodeAt(n);
            }
            return new Blob([u8arr], {
                type: 'image/png',
            });
        } catch (err) {
            console.log(err.message);
        }
    }
}

export default Thematic;
